<template>
  <div class="page-common-layout custom-tablePage-container">
    <div class="page-body" :class="fullScreenStatus && 'full-screen'">
      <!-- 图例 -->
      <div class="legend-warp">
        <!-- 展开/折叠 -->
        <a-button @click="expandTreeTable()" style="margin:0 auto 0 10px;">
          <a-icon type="swap" />
          展开/折叠
        </a-button>
        <div
          class="legend-item"
          v-for="(item, index) in nodeLevelSource"
          :key="index"
          :class="getLegendClass(item.dicItemCode)"
        >
          {{ item.dicItemName }}
        </div>
        <a-dropdown style="margin-left:10px">
          <a-menu slot="overlay" @click="ganttChangeDate($event)">
            <a-menu-item :key="1"> 日视图 </a-menu-item>
            <a-menu-item :key="2"> 周视图 </a-menu-item>
            <a-menu-item :key="3"> 月视图 </a-menu-item>
            <a-menu-item :key="4"> 季视图 </a-menu-item>
          </a-menu>
          <a-button> {{ ganttText }} <a-icon type="down" /> </a-button>
        </a-dropdown>

        <!-- 全屏按钮 -->
        <div class="full-scree-btn">
          <div
            class="btn"
            @click="handleFullScreen()"
            :title="fullScreenStatus ? '退出全屏' : '全屏'"
          >
            <a-icon
              :type="fullScreenStatus ? 'fullscreen-exit' : 'fullscreen'"
            />
          </div>
        </div>
      </div>
      <!--  -->
      <div class="table-container">
        <!-- 列表 -->
        <div class="table-warp" :style="{ width: leftWidth + '%' }">
          <vxe-table
            row-id="uuid"
            resizable
            border="inner"
            height="99%"
            show-overflow
            keep-source
            highlight-hover-row
            highlight-current-row
            ref="xTreeTable"
            :loading="tableLoading"
            :tree-config="{
              transform: true,
              rowField: 'uuid',
              parentField: 'parentId',
              childrenField: 'childList',
              reserve: true,
            }"
            :checkbox-config="{ labelField: 'id' }"
            :data="tableData"
            :row-config="{ isHover: true }"
            @cell-click="onRowClick"
            @toggle-tree-expand="handleToggleTreeExpand"
          >
            <vxe-column
              type="seq"
              width="80"
              title="序号"
              align="center"
            ></vxe-column>
            <vxe-table-column
              field="name"
              title="任务名称"
              min-width="200"
              tree-node
            ></vxe-table-column>
            <vxe-table-column
              field="planStartTime"
              title="计划开始时间"
              width="160"
            ></vxe-table-column>
            <vxe-table-column
              field="planEndTime"
              title="计划结束时间"
              width="160"
            ></vxe-table-column>
            <vxe-table-column field="duration" title="周期（天）" width="150">
            </vxe-table-column>
            <vxe-table-column field="major" title="关键节点" width="160">
              <template #default="{ row }">
                <div class="keyNode" :class="row.major == 1 && 'is'">
                  {{ row.major == 1 ? "是" : "否" }}
                </div>
              </template>
            </vxe-table-column>
            <vxe-table-column field="date" title="前置任务" width="100">
              <template #default="{ row }">
                <icon-font
                  v-if="row.parentId"
                  class="qianzhirenwu-td"
                  type="icon-qianzhirenwu"
                  @click="viewPreTask(row)"
                ></icon-font>
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="nodeLevelDesc"
              title="节点等级"
              width="160"
            >
            </vxe-table-column>
            <vxe-table-column field="status" title="状态" width="140">
              <template #default="{ row }">
                <div class="status-td" :class="getStatusClass(row.status)">
                  {{ getStatusName(row.status) }}
                </div>
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="actualStartTime"
              title="实际开始时间"
              width="160"
            ></vxe-table-column>
            <vxe-table-column
              field="actualEndTime"
              title="实际结束时间"
              width="160"
            ></vxe-table-column>
            <vxe-table-column title="偏差天数" width="100">
              <template #default="{ row }">
                {{ getValue(row, "deviationDays") }}
              </template>
            </vxe-table-column>
            <vxe-table-column title="偏差原因" width="160">
              <template #default="{ row }">
                {{ getValue(row, "deviationReason") }}
              </template>
            </vxe-table-column>
            <vxe-table-column title="成果文件" width="160" align="center">
              <template #default="{ row }">
                <a-tooltip placement="top" v-if="isShowFileIcon(row)">
                  <template slot="title">
                    预览
                  </template>
                  <a-icon
                    type="eye"
                    class="preview-btn"
                    @click="viewOutcomeFile(row)"
                  />
                </a-tooltip>
              </template>
            </vxe-table-column>
          </vxe-table>
          <!-- 拖拽按钮【table】 -->
          <div
            class="divider-button"
            v-if="openType != 2"
            :class="openType == 1 && 'table'"
            @click="handleOpen(openType == 1 ? 0 : 1)"
          ></div>
        </div>
        <!--  -->
        <div
          class="drag-button-warp"
          @mousedown="startDrag"
          v-if="openType == 0"
        ></div>
        <!-- 甘特图 -->
        <div class="gantt-chart-container" :style="{ width: rightWidth + '%' }">
          <!-- 拖拽按钮【甘特图】 -->
          <div
            class="divider-button"
            :class="openType == 2 && 'gantt'"
            @click="handleOpen(openType == 2 ? 0 : 2)"
          ></div>
          <div class="gantt-container" ref="gantt" v-if="isEmpty"></div>
          <a-empty :image="simpleImage" v-else />
        </div>
      </div>
      <!-- 进度条 -->
      <div class="progress-header">
        <div class="date-container">
          <div class="date-value">
            <!-- 日期 -->
            <a-range-picker
              :disable="isPlay"
              :placeholder="['开始日期', '开始日期']"
              format="YYYY-MM-DD"
              valueFormat="YYYY-MM-DD"
              @change="dateChange($event)"
              v-model="dateTime"
            >
              <a-icon slot="suffixIcon" type="calendar" />
            </a-range-picker>
            <!-- 计划类型 -->
            <a-select
              placeholder="计划类型"
              style="width: 200px;margin-left:16px;"
              v-model="moduleSource"
              @change="changeNodeType($event)"
            >
              <a-select-option
                :value="item.dicItemCode"
                v-for="(item, index) in nodeTypeSource"
                :key="index"
              >
                {{ item.dicItemName }}
              </a-select-option>
            </a-select>
          </div>
        </div>
        <div
          class="control-container"
          id="control-container"
          v-if="dateList.length > 0"
        >
          <a-tooltip v-if="!isPlay">
            <template slot="title"> 开始 </template>
            <a-icon
              type="play-circle"
              theme="filled"
              class="icon"
              @click="
                isPlay = true;
                navgControl('start');
              "
            />
          </a-tooltip>
          <a-tooltip v-else>
            <template slot="title"> 暂停 </template>
            <a-icon
              type="pause-circle"
              theme="filled"
              class="icon"
              @click="
                isPlay = false;
                navgControl('pause');
              "
            />
          </a-tooltip>

          <a-slider
            class="progress-slider"
            v-model="silder.value"
            :tip-formatter="tipFormat"
            :tooltip-visible="silder.tooltipVisible"
            :step="10"
            :max="silder.max"
            :min="silder.min"
            @change="handleSliderChange($event)"
            :getTooltipPopupContainer="getTooltipPopupContainer"
          >
          </a-slider>
        </div>
        <div class="operate-container" v-if="dateList.length > 0">
          <!-- 倍速 -->
          <div
            class="play-speed"
            @mouseenter="isTimesChoose = true"
            @mouseleave="isTimesChoose = false"
          >
            <div class="times-show">
              {{ times == 1 ? "倍速" : times + "x" }}
            </div>
            <div class="choose-box">
              <ul v-show="isTimesChoose">
                <li
                  v-for="item in speedList"
                  :key="item"
                  :class="{ active: times == item }"
                  @click="changeSpeed(item)"
                >
                  {{ item }}X
                </li>
              </ul>
            </div>
          </div>
          <div @click="navgControl('reset')">
            <a-tooltip>
              <template slot="title"> 重置 </template>
              <icon-font
                type="icon-gengxin"
                style="font-size:18px;color:#ea9356"
              ></icon-font>
            </a-tooltip>
          </div>
        </div>
      </div>
    </div>
    <!-- 前置任务 -->
    <pretaskModal
      :visible.sync="pretask.visible"
      :operate="pretask.type"
      :versionInfo="currentVersion"
      :row="pretask.row"
      @change="handlePretaskChange($event)"
    ></pretaskModal>
    <!-- 多文件 -->
    <viewFileModal
      :visible.sync="viewFileModal.visible"
      :fileList="viewFileModal.fileList"
      :subtitle="viewFileModal.name"
      :replaceFields="{
        fileName: 'fileName',
      }"
    ></viewFileModal>
  </div>
</template>

<script>
import { Empty } from "ant-design-vue";
import gantt from "dhtmlx-gantt";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
import { getDicItemByCode } from "@/api/common.js";
import { Icon } from "ant-design-vue";
import iconfrontjs from "@/assets/IconFont/iconfont.js";
//多文件预览
import viewFileModal from "@/components/extendCustom/view-file-modal";
const iconFrontUrl = iconfrontjs;
const IconFont = Icon.createFromIconfontCN({
  scriptUrl: iconFrontUrl,
});
//前置任务【弹窗】
import pretaskModal from "../components/components/pretaskModal.vue";
import { getPlanControlVersion, getTableData } from "@/api/progressManage";
export default {
  props: {},
  provide() {
    return {
      moduleSource: () => this.moduleSource,
    };
  },
  components: {
    IconFont,
    pretaskModal,
    viewFileModal,
  },
  data() {
    return {
      //表格全部展开状态
      treeTableExpandAll: false,
      //多文件预览
      viewFileModal: {
        name: "",
        visible: false,
        fileList: [],
      },
      dateTime: [],
      moduleSource: "scheduleType.01",
      //前置任务
      pretask: {
        visible: false,
        operate: 0,
        row: {},
      },
      //全屏状态
      fullScreenStatus: false,
      //节点等级列表
      nodeLevelSource: [],
      leftWidth: 50,
      rightWidth: 50,
      isDragging: false,
      startX: 0,
      openType: 0,
      //进度条
      //选择速度弹窗的open/close
      isTimesChoose: false,
      dateList: [],
      //是否为播放
      isPlay: false,
      //几倍速度播放
      times: 1,
      //播放倍率
      speedList: ["16.0", "10.0", "5.0", "2.0", "1.0", "0.5", "0.25"],
      //进度条滑动速度
      silder: {
        resSetFlag: false,
        playStatus: "",
        playInterval: null,
        min: 0,
        max: 10,
        value: 0,
        tooltipVisible: false,
        stepIndex: -2,
      },
      //版本信息
      currentVersion: {},
      tableData: [],
      tableLoading: false,
      //甘特图数据
      ganttData: {
        data: [],
        links: [],
      },
      //计划类型
      nodeTypeSource: [],
      //所有数据
      trackSource: [],
      //
      ganttText: "日视图",
      ganttKeyWord: 1,
      isEmpty: false,
    };
  },
  beforeCreate() {
    this.simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
  },
  mounted() {
    this.getNodeLevelData();
    this.getVersionData();
    this.getNodeTypeData();
    gantt.templates.task_class = (start, end, task) => {
      let { type } = task;
      return type?.replace(".", "") || "";
    };
  },
  methods: {
    //【table】展开.折叠表格
    expandTreeTable() {
      let { treeTableExpandAll } = this;
      this.$refs.xTreeTable.setAllTreeExpand(
        !treeTableExpandAll ? true : false
      );
      this.treeTableExpandAll = !this.treeTableExpandAll;
    },

    //偏差天数、原因
    getValue(row = {}, key = "") {
      try {
        let { scheduleItemFill } = row;
        return scheduleItemFill?.[key];
      } catch (error) {
        return "--";
      }
    },

    //
    isShowFileIcon(row) {
      try {
        let { scheduleItemFill } = row;
        let { files } = scheduleItemFill;
        let fileList = JSON.parse(files);
        return fileList.length > 0;
      } catch (error) {
        return false;
      }
    },

    //预览成果文件
    viewOutcomeFile(row = {}) {
      try {
        let { scheduleItemFill, name } = row;
        let { files } = scheduleItemFill;
        let fileList = JSON.parse(files);
        this.viewFileModal.name = name;
        this.viewFileModal.fileList = fileList ?? [];
        this.viewFileModal.visible = true;
      } catch (error) {}
    },

    //查询版本号
    getVersionData() {
      this.tableLoading = true;
      return new Promise((reslove, reject) => {
        getPlanControlVersion({
          type: "scheduleType.01",
          orgCode: "",
        })
          .then((res) => {
            let source = res?.data ?? {};
            this.currentVersion = source;
            reslove();
          })
          .catch(() => {
            this.currentVersion = {};
            reject();
          })
          .finally((_) => {
            this.getData();
          });
      });
    },

    //打开前置任务弹窗
    viewPreTask(row = {}) {
      let isActiveByRow = this.$refs.xTreeTable.isActiveByRow(row);
      this.pretask.type = isActiveByRow ? 1 : 0;
      this.pretask.row = row;
      this.pretask.visible = true;
    },

    //状态名称
    getStatusName(status) {
      switch (Number(status)) {
        case 0:
          return "未开始";

        case 1:
          return "延期未开始";

        case 2:
          return "进行中";

        case 3:
          return "延期已开始";

        case 4:
          return "延期未完成";

        case 5:
          return "已完成";

        case 6:
          return "延期完成";

        default:
          return "未开始";
      }
    },

    //状态样式
    getStatusClass(status) {
      switch (Number(status)) {
        //未开始
        case 0:
          return "wks";

        //延期未开始
        case 1:
          return "yqwks";

        //进行中
        case 2:
          return "ing";

        //延期已开始
        case 3:
          return "yqyks";

        //延期未完成
        case 4:
          return "yqwwc";

        //已完成
        case 5:
          return "ywc";

        //延期完成
        case 6:
          return "yqwc";

        default:
          return "wks";
      }
    },

    //查询table
    getData() {
      this.tableLoading = true;
      return new Promise((resolve, reject) => {
        getTableData({
          showAll: 1,
          ganttChart: 1,
          track: 1,
          versionId: this.currentVersion?.uuid || "",
          nodeType: this.moduleSource,
          proCode: "",
          orgCode: "",
          startDate: this.dateTime?.[0] || "",
          endDate: this.dateTime?.[1] || "",
        })
          .then((res) => {
            let { data } = res;
            this.tableData = data?.dataList || [];
            this.dateList = data?.dateList || [];
            this.trackSource = data?.trackList || [];

            // this.ganttData.data.forEach()

            //甘特图数据
            this.ganttData.data = data?.chartList ?? [];
            this.ganttData.links = data?.preList ?? [];

            if (this.ganttData.data.length > 0) {
              this.isEmpty = true;
              //   甘特图数据
              this.$nextTick(() => {
                this.initGantt();
              });
            } else {
              this.isEmpty = false;
            }

            try {
              // 监听任务点击事件
              gantt.attachEvent("onTaskClick", (id, e) => {
                let { tableData } = this;
                let aboutRow = tableData.find((v) => v.chartId == id);
                let tableRef = this.$refs.xTreeTable;
                if (aboutRow && tableRef) {
                  tableRef.setCurrentRow(aboutRow);
                }
                return true;
              });
            } catch (error) {}
            resolve();
          })
          .catch((_) => {
            this.trackSource = [];
            this.dateList = [];
            this.tableData = [];
            this.ganttData.data = [];
            this.ganttData.links = [];
            reject();
          })
          .finally((_) => {
            this.tableLoading = false;
          });
      });
    },

    //监听表格点击事件
    onRowClick(record) {
      let { row } = record;
      let { chartId, $$TYPE, childList } = row;
      if ($$TYPE != "temporarily" && (!childList || childList.length == 0)) {
        // 选中任务
        gantt.selectTask(chartId);
        // 滚动到任务位置
        gantt.showTask(chartId);
      }
    },

    //监听树形表格展开、收起
    handleToggleTreeExpand({ expanded, row }) {
      let { chartId } = row;
      if (expanded) {
        //展开 Gantt 图中的任务节点
        gantt.open(chartId);
      } else {
        //收起 Gantt 图中的任务节点
        gantt.close(chartId);
      }
    },
    ganttChangeDate(info) {
      let { key } = info;
      this.ganttKeyWord = key;
      switch (key) {
        case 1:
          this.ganttText = "日视图";
          break;
        case 2:
          this.ganttText = "周视图";
          break;
        case 3:
          this.ganttText = "月视图";
          break;
        case 4:
          this.ganttText = "季视图";
          break;
        default:
          break;
      }
      this.$nextTick(() => {
        this.initGantt();
      });
    },

    //初始化-甘特图
    initGantt() {
      // 清空之前的配置
      gantt.clearAll();
      // 设置中文
      gantt.i18n.setLocale("cn");
      //自定义左侧 头部列的内容
      gantt.config.columns = [
        {
          name: "id",
          label: "序号",
          align: "center",
          width: "50",
          template: function(obj) {
            return obj.sortIndex;
          },
        },
        {
          name: "text", //在tasks.data中定义的属性数据，add为例外,add为新增数据项触发gantt新增弹窗，显示为一个加
          label: "任务名称", //标记描述
          tree: true, //相关列应显示树
          width: "200", //宽度，可写max _width min_width
          align: "left", //文字格式
          resize: true, //布尔值，可以拉伸内容宽度
          template: function(obj) {
            return obj.text;
          },
        },
        {
          name: "duration",
          label: "周期",
          align: "center",
          width: "50",
          template: function(obj) {
            return obj.duration;
          },
        },
        {
          name: "start_date",
          label: "计划开始时间",
          align: "center",
          width: "100",
          template: function(obj) {
            return obj.start_date;
          },
        },
        {
          name: "end_date",
          label: "计划完成时间",
          align: "center",
          width: "100",
          template: function(obj) {
            return obj.end_date;
          },
        },
      ];
      //   gantt.config.grid_width = 0;
      //时间轴图表中-日期展示格式
      let { ganttKeyWord } = this;
      switch (ganttKeyWord) {
        //日视图
        case 1:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年-%M" },
            { unit: "day", format: "%d" },
          ];
          break;

        //周视图
        case 2:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年-%M" },
            { unit: "week", format: "第%w周" },
          ];
          break;

        //月视图
        case 3:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年" },
            { unit: "month", step: 1, format: "%M" },
          ];
          break;

        //季度视图
        case 4:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年" },
            { unit: "quarter", step: 1, format: quarterLabel },
          ];
          break;
        default:
          break;
      }
      function quarterLabel(date) {
        var month = date.getMonth();
        var q_num;

        if (month >= 9) {
          q_num = "四";
        } else if (month >= 6) {
          q_num = "三";
        } else if (month >= 3) {
          q_num = "二";
        } else {
          q_num = "一";
        }
        return "第" + q_num + "季度";
      }
      // 鼠标经过打开 tooltip 提示
      gantt.plugins({
        tooltip: false,
        // 拖动图
        drag_timeline: true,
      });
      gantt.templates.tooltip_text = function(start, end, task) {
        return `
          <div style="font-weight: 400;font-size: 16px;color: #2B2C30;font-family: Microsoft YaHei;margin-bottom: 10px;"> ${
            task.text
          }</div>
          <div style="font-weight: 400;font-size: 14px;color: #666666;font-family: Microsoft YaHei;margin-bottom: 8px;">计划开始时间：${gantt.templates.tooltip_date_format(
            start
          )}</div>
          <div style="font-weight: 400;font-size: 14px;color: #666666;font-family: Microsoft YaHei;margin-bottom: 8px;">计划结束时间：${gantt.templates.tooltip_date_format(
            end
          )}</div>
           <div style="font-weight: 400;font-size: 14px;color: #666666;font-family: Microsoft YaHei;margin-bottom: 8px;">周期：${
             task.duration
           }</div>
              `;
      };
      //滚动条布局
      gantt.config.scroll_size = 12;
      gantt.config.layout = {
        css: "gantt_container",
        // rows: [
        //   {
        //     cols: [
        //       { view: "timeline", scrollY: "scrollVer", scrollX: "scrollHor" },
        //     ],
        //   },
        //   { view: "scrollbar", id: "scrollHor", height: 20 },
        // ],
        cols: [
          //   {
          //     width: 500,
          //     rows: [
          //       {
          //         view: "grid",
          //         scrollX: "gridScroll",
          //         scrollable: true,
          //         scrollY: "scrollVer",
          //       },
          //       { view: "scrollbar", id: "gridScroll", group: "horizontal" },
          //     ],
          //   },
          { resizer: true, width: 1 },
          {
            rows: [
              { view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
              { view: "scrollbar", id: "scrollHor", group: "horizontal" },
            ],
          },
          { view: "scrollbar", id: "scrollVer" },
        ],
      };
      gantt.config.scale_height = 48;
      gantt.config.row_height = 48;
      //取消右边表格进度条显示与拖动
      gantt.config.show_progress = false;
      //用户可以通过拖拽调整行高
      gantt.config.resize_rows = true;
      //时间轴图表中  设置图例高度
      gantt.config.bar_height = 25;
      // 只读模式：打开后不可以操作甘特图
      gantt.config.readonly = true;
      // 初始化甘特图  可以通过ref挂载 或者 id选择器挂载
      gantt.init(this.$refs.gantt);
      // 渲染数据
      gantt.parse(this.ganttData);
      //建议每一次修改配置项调用一次render方法
      gantt.render();
    },

    //播放甘特图
    playGantt(index) {
      if (index >= 0) {
        this.silder.tooltipVisible = true;
      } else {
        this.silder.tooltipVisible = false;
      }

      this.tableData = this.trackSource[index]?.dataList ?? [];
      this.ganttData.data = this.trackSource[index]?.chartList ?? [];
      this.ganttData.data.forEach((item) => {
        item.parent = null;
      });
      this.$nextTick(() => {
        setTimeout(() => {
          this.initGantt();
        }, 500);
      });
    },

    //重置甘特图
    resetGantt() {
      //选择速度弹窗的open/close
      this.isTimesChoose = false;
      this.dateList = [];
      //是否为播放
      this.isPlay = false;
      //几倍速度播放
      this.times = 1;
      //播放倍率
      this.speedList = ["16.0", "10.0", "5.0", "2.0", "1.0", "0.5", "0.25"];
      //进度条滑动速度
      this.silder = {
        resSetFlag: false,
        playStatus: "",
        playInterval: null,
        min: 0,
        max: 10,
        tooltipVisible: false,
        stepIndex: -2,
        value: -2,
      };
      this.trackSource = [];
      this.dateList = [];
      this.tableData = [];
      this.ganttData.data = [];
      this.ganttData.links = [];
      this.getData();
    },

    //查询节点等级列表
    getNodeTypeData() {
      return new Promise((resolve, reject) => {
        getDicItemByCode({ code: "scheduleType" })
          .then((res) => {
            let { data } = res;
            this.nodeTypeSource = data ?? [];
            resolve();
          })
          .catch((_) => {
            this.nodeTypeSource = [];
            reject();
          })
          .finally((_) => {});
      });
    },

    //查询节点等级列表
    getNodeLevelData() {
      return new Promise((resolve, reject) => {
        getDicItemByCode({ code: "nodeLevel" })
          .then((res) => {
            let { data } = res;
            this.nodeLevelSource = data ?? [];
            resolve();
          })
          .catch((_) => {
            this.nodeLevelSource = [];
            reject();
          })
          .finally((_) => {});
      });
    },

    //监听日期切换
    async dateChange(ev) {
      this.resetGantt();
    },

    changeNodeType() {
      this.resetGantt();
    },

    // 开始、暂停、继续等操作
    async navgControl(action) {
      this.initSilder();
      //倍速
      switch (action) {
        //播放
        case "start":
          this.play();
          break;

        //暂停
        case "pause":
          if (this.silder.playInterval) {
            clearInterval(this.silder.playInterval);
            this.silder.playInterval = null;
          }
          break;

        //重置
        case "reset":
          this.resetSilder();
          this.resetGantt();
          this.isPlay = false;
          break;

        default:
          break;
      }
    },

    //播放
    async play(type = 0) {
      let { dateList } = this;
      let { times } = this;
      if (this.silder.value == (dateList.length - 1) * 10 && !type) {
        this.resetSilder();
        this.silder.resSetFlag = false;
        await this.sleep(600);
      }
      this.silder.stepIndex++;
      this.silder.value = this.silder.stepIndex * 10;
      this.silder.playInterval = setInterval(() => {
        this.silder.stepIndex++;
        this.silder.value = this.silder.stepIndex * 10;
        if (this.silder.stepIndex == dateList.length - 1) {
          this.isPlay = false;
          clearInterval(this.silder.playInterval);
        }
        //
        this.playGantt(this.silder.stepIndex);
      }, 1000 / times);
    },

    //重置silder
    resetSilder() {
      this.silder.resSetFlag = true;
      if (this.silder.playInterval) {
        clearInterval(this.silder.playInterval);
        this.silder.playInterval = null;
      }
      //   this.silder.stepIndex = 0;
      //   this.silder.value = 0;
      this.silder.value = -2;
      this.silder.stepIndex = -2;
      this.silder.tooltipVisible = false;
      this.isPlay = false;
    },

    //初始化silder
    initSilder() {
      let { dateList } = this;
      let stepNums = dateList.length - 1;
      this.silder.max = stepNums >= 1 ? stepNums * 10 : 0;
    },

    //监听silder变化
    handleSliderChange(value) {
      this.silder.resSetFlag = false;
      this.silder.stepIndex = value / 10;
      //
      this.playGantt(this.silder.stepIndex);
    },

    tipFormat() {
      return this.dateList[this.silder.stepIndex];
    },

    //睡眠函数
    sleep(ms) {
      return new Promise((resolve) => setTimeout(resolve, ms));
    },

    formatterNumber(value) {
      if (value) {
        return value + "%";
      } else {
        return value;
      }
    },

    //修改倍速
    changeSpeed(times) {
      this.isTimesChoose = false;
      this.times = times;
      if (!this.isPlay) {
        return;
      }
      if (this.silder.playInterval) {
        clearInterval(this.silder.playInterval);
        this.silder.playInterval = null;
      }
      this.play(1);
    },

    getTooltipPopupContainer() {
      return document.getElementById("control-container");
    },

    handleOpen(type) {
      this.openType = type;
      switch (type) {
        case 1:
          this.leftWidth = 100;
          this.rightWidth = 0;
          break;

        case 2:
          this.leftWidth = 0;
          this.rightWidth = 100;
          break;

        default:
          this.leftWidth = 50;
          this.rightWidth = 50;
          break;
      }
    },

    startDrag(event) {
      this.isDragging = true;
      this.startX = event.clientX;
      document.addEventListener("mousemove", this.onDrag);
      document.addEventListener("mouseup", this.stopDrag);
    },

    onDrag(event) {
      if (!this.isDragging) return;
      requestAnimationFrame(() => {
        const deltaX = event.clientX - this.startX;
        const containerWidth = this.$el.clientWidth;
        const deltaPercent = (deltaX / containerWidth) * 100;
        let newLeftWidth = this.leftWidth + deltaPercent;
        let newRightWidth = this.rightWidth - deltaPercent;

        // 限制宽度范围
        // if (newLeftWidth < 10) {
        //   newLeftWidth = 10;
        //   newRightWidth = 90;
        // } else if (newRightWidth < 10) {
        //   newLeftWidth = 90;
        //   newRightWidth = 10;
        // }

        this.leftWidth = newLeftWidth;
        this.rightWidth = newRightWidth;
        this.startX = event.clientX;
      });
    },

    stopDrag() {
      this.isDragging = false;
      document.removeEventListener("mousemove", this.onDrag);
      document.removeEventListener("mouseup", this.stopDrag);
    },

    getLegendClass(code = "") {
      return code?.replace(".", "") || "";
    },

    //全屏
    handleFullScreen() {
      this.fullScreenStatus = !this.fullScreenStatus;
    },
  },
};
</script>

<style lang="less" scoped>
.custom-tablePage-container {
  position: relative;
  overflow: hidden;
  .page-body {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #f0f2f5;
    &.full-screen {
      position: fixed;
      top: 0;
      left: 0;
      z-index: 999;
      border-radius: 0;
    }
    .legend-warp {
      display: flex;
      padding-right: 16px;
      height: 56px;
      align-items: center;
      background: #fff;
      justify-content: flex-end;
      .legend-item {
        display: flex;
        flex-wrap: nowrap;
        align-items: center;
        color: #666666;
        font-size: 14px;
        &:not(:first-child) {
          margin-left: 14px;
        }
        &::before {
          content: "";
          display: flex;
          width: 20px;
          height: 12px;
          background: #5b78f2;
          border-radius: 2px;
          margin-right: 4px;
        }
        &.nodeLevel01 {
          &::before {
            background-color: #5b78f2;
          }
        }
        &.nodeLevel02 {
          &::before {
            background-color: #35b2e1;
          }
        }
        &.nodeLevel03 {
          &::before {
            background-color: #9286ec;
          }
        }
        &.nodeLevel04 {
          &::before {
            background-color: #f07f17;
          }
        }
        &.nodeLevel05 {
          &::before {
            background-color: #f45d5d;
          }
        }
        &.nodeLevel06 {
          &::before {
            background-color: #51bc64;
          }
        }
        &.nodeLevel07 {
          &::before {
            background-color: #d251d4;
          }
        }
        &.nodeLevel08 {
          &::before {
            background-color: #27bead;
          }
        }
      }
      .full-scree-btn {
        height: 100%;
        border-radius: 0 4px 4px 0;
        margin-left: 16px;
        box-sizing: border-box;
        display: flex;
        align-items: center;
        .btn {
          cursor: pointer;
          width: 24px;
          height: 24px;
          background: #ffffff;
          border-radius: 4px;
          border: 1px solid #d9d9d9;
          display: flex;
          align-items: center;
          justify-content: center;
          color: #8c8c8c;
        }
      }
    }
    .table-container {
      flex: 1;
      background: #fff;
      display: flex;
      overflow: hidden;
      .table-warp {
        position: relative;
        padding-left: 10px;
        box-sizing: border-box;
        .preview-btn {
          color: #1890ff;
          font-size: 16px;
        }
        /deep/.vxe-table {
          .row--current {
            background-color: #fff3a1 !important;
          }
          .vxe-table--fixed-right-wrapper {
            border-top: 1px solid #e8eaec;
            border-right: 1px solid #e8eaec;
          }
          .vxe-table--main-wrapper {
            border-left: 1px solid #e8eaec;
            border-right: 1px solid #e8eaec;
            border-top: 1px solid #e8eaec;
          }
        }
        .qianzhirenwu-td {
          color: #1677ff;
          font-size: 18px;
          cursor: pointer;
        }
        .status-td {
          color: #333333;
          display: flex;
          align-items: center;
          &::before {
            flex-shrink: 0;
            content: "";
            display: flex;
            width: 8px;
            height: 8px;
            background: #8c8c8c;
            border-radius: 50%;
            margin-right: 8px;
          }
          //未开始
          &.wks {
            &::before {
              background: #8c8c8c;
            }
          }

          //延期未开始
          &.yqwks {
            &::before {
              background: #ff3f4a;
            }
          }
          //进行中
          &.ing {
            &::before {
              background: #1677ff;
            }
          }
          //延期已开始
          &.yqyks {
            &::before {
              background: #f07f17;
            }
          }
          //延期未完成
          &.yqwwc {
            &::before {
              background: #df2732;
            }
          }
          //已完成
          &.ywc {
            &::before {
              background: #2fba4b;
            }
          }
          //延期完成
          &.yqwc {
            &::before {
              background: #f07f17;
            }
          }
        }
        .keyNode {
          color: #ff3f4a;
          &.is {
            color: #239b53;
          }
        }
        .divider-button {
          right: 0;
        }
      }
      .gantt-chart-container {
        position: relative;
        padding-right: 10px;
        box-sizing: border-box;
        .divider-button {
          left: 0;
          background: url("~@/assets/img/icon_15.png");
          background-size: 100% 100%;
        }
        .gantt-container {
          height: 100%;
          width: 100%;
        }

        /deep/.gantt_task_line {
          &.nodeLevel01 {
            background-color: #5b78f2;
          }
          &.nodeLevel02 {
            background-color: #35b2e1;
          }
          &.nodeLevel03 {
            background-color: #9286ec;
          }
          &.nodeLevel04 {
            background-color: #f07f17;
          }
          &.nodeLevel05 {
            background-color: #f45d5d;
          }
          &.nodeLevel06 {
            background-color: #51bc64;
          }
          &.nodeLevel07 {
            background-color: #d251d4;
          }
          &.nodeLevel08 {
            background-color: #27bead;
          }
        }

        /deep/.ant-empty {
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
        }
      }
      // 拖拽按钮
      .drag-button-warp {
        height: 100%;
        width: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        position: relative;
        cursor: ew-resize;
        user-select: none;
        z-index: 99;
        &::before {
          content: "";
          height: 100%;
          position: absolute;
          width: 1px;
          border-left: 1px dashed #cecece;
          left: 50%;
          top: 0;
          transform: translateX(-50%);
          opacity: 0;
        }
        &::after {
          position: absolute;
          content: "";
          width: 14px;
          height: 13px;
          background: url("~@/assets/img/icon_18.png");
          background-size: 100% 100%;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
        }
        &:hover {
          &::before {
            opacity: 1;
          }
        }
      }
      .divider-button {
        user-select: none;
        cursor: ew-resize;
        position: absolute;
        width: 28px;
        height: 40px;
        background: url("~@/assets/img/icon_14.png");
        background-size: 100% 100%;
        top: 50%;
        transform: translateY(-50%);
        margin-top: 34px;
        z-index: 99;
        &.table {
          background: url("~@/assets/img/icon_15.png");
          background-size: 100% 100%;
        }
        &.gantt {
          background: url("~@/assets/img/icon_14.png");
          background-size: 100% 100%;
        }
      }
    }
    .progress-header {
      height: 64px;
      background: #fff;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 24px;
      margin-top: 10px;
      .date-container {
        display: flex;
        align-items: center;
        .date-name {
          margin-right: 10px;
          font-family: Microsoft YaHei;
          font-weight: 400;
          font-size: 14px;
          color: #2a2b2f;
          letter-spacing: 1px;
        }
        .date-value {
          /deep/.ant-calendar-picker {
            width: 248px;
            .ant-input {
              background: #ffffff;
              border: 1px solid #f2f2f2;
              font-family: Microsoft YaHei;
              font-weight: 400;
              font-size: 14px;
              .ant-calendar-range-picker-separator {
              }
              .anticon-calendar {
              }
            }
          }
        }
      }
      .control-container {
        flex: 1;
        padding: 0 20px 0 24px;
        display: flex;
        align-items: center;
        .icon {
          font-size: 34px;
          color: #1677ff;
        }

        .progress-slider {
          flex: 1;
          margin-left: 40px;
          /deep/.ant-slider-rail {
            background: rgba(69, 146, 255, 0.1);
          }
        }
      }
      .operate-container {
        position: relative;
        cursor: pointer;
        display: flex;
        align-items: center;
        .middle {
          font-size: 24px !important;
        }
        .play-speed {
          display: flex;
          position: relative;
          width: 50px;
          justify-content: center;
          align-items: center;
          margin-top: -2px;
          margin-right: 6px;
          .times-show {
            font-family: Microsoft YaHei, Microsoft YaHei;
            font-weight: 400;
            font-size: 14px;
            color: #1677ff;
            cursor: default;
          }
          .choose-box {
            position: absolute;
            top: -240px;
            left: -18px;
            height: 162px;
            transition: all 0.5s linear;
            ul {
              width: 74px;
              background: rgba(255, 255, 255, 0.9);
              box-shadow: 0px 0px 8px 0px rgba(153, 153, 153, 0.2);
              border-radius: 4px;
              padding: 4px 0;
              text-align: center;
              li {
                height: 34px;
                line-height: 34px;
                color: #999999;
                list-style: none;
                cursor: pointer;
                &.active {
                  color: #0098ff;
                }
                &:hover {
                  color: #0098ff;
                  font-size: 13px;
                }
              }
            }
          }
        }
        .transparent-bar {
          position: absolute;
          top: -48px;
          left: -20px;
          width: 160px;
          height: 40px;
          background: #ffffff;
          border-radius: 4px 4px 4px 4px;
          display: flex;
          align-items: center;
          padding: 13px 16px;
          .terrain {
            width: 160px;
          }
          .ant-input-number {
            width: 158px;
          }
        }

        .set-up {
          color: #49cada;
          margin-right: 16px;
          &.active {
            color: #1677ff;
          }
        }
        .refresh {
          color: #ea9356;
        }

        .open-container {
          margin-left: 20px;
          display: flex;
          align-items: center;
          font-family: Microsoft YaHei;
          font-weight: 400;
          font-size: 14px;
          color: #666666;
          /deep/.anticon-down-circle,
          .anticon-up-circle {
            font-size: 20px;
            margin-left: 8px;
          }
        }
      }
    }
  }
}
</style>
<style lang="less">
.gantt_tooltip {
  z-index: 999;
}
</style>
